"""
Case Type   : 资源池化集群系统故障模式库
Case Name   : 控制文件损坏
Create At   : 2025/04/20
Owner       : @kyleze
Description :
    1.获取控制文件位置，并破坏文件
    2.连接数据库
    3.重启数据库
    4.恢复文件
    5.启动数据库
    6.连接数据库，查询集群状态
Expect      :
    1.成功
    2.成功
    3.失败
    4.成功
    5.成功
    6.连接成功，集群状态正常
History     :
"""

import os
import unittest

from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH

from yat.test import Node
from yat.test import macro


@unittest.skipIf(
    "dms_res" not in Common().get_sh_result(
        Node("PrimaryDbUser"),
        f"source {macro.DB_ENV_PATH};cm_ctl query -Cvidp"), "非资源池化不执行")
class SharedStorageFaultsMode(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"----{os.path.basename(__file__)} start----")
        self.constant = Constant()
        self.com = Common()
        self.primary_sh = CommonSH("PrimaryDbUser")
        self.primary_node = Node("PrimaryDbUser")
        self.primary_root = Node("PrimaryRoot")
        self.table_name = "t_faults_test0120"
        self.index_name = "i_faults_test0120"

    def test_faults_mode(self):
        step = "--step1:获取控制文件位置，并破坏文件 expect:成功--"
        self.logger.info(step)
        cmd = f'source {macro.DB_ENV_PATH};' \
              f'cat $DSS_HOME/cfg/dss_vg_conf.ini |cut -d ":" -f 1'
        vgname_infor = self.primary_node.sh(cmd).result().strip()
        self.logger.info(vgname_infor)
        data_vgname = vgname_infor.split('\n')[0].strip()
        ls_cmd = f"source {macro.DB_ENV_PATH};" \
                 f"dsscmd ls -p +{data_vgname}/pg_control"
        self.logger.info(ls_cmd)
        ls_res = self.primary_node.sh(ls_cmd).result().strip()
        self.logger.info(ls_res)
        self.assertIn('pg_control', ls_res, "执行失败:" + step)
        truncate_cmd = f"source {macro.DB_ENV_PATH};" \
                       f"dsscmd truncate -p +{data_vgname}/pg_control -l 100"
        self.logger.info(truncate_cmd)
        truncate_res = self.primary_node.sh(truncate_cmd).result().strip()
        self.logger.info(truncate_res)
        self.assertEqual("Success to truncate file", truncate_res,
                         "执行失败:" + step)

        step = "----step2:连接数据库 expect:失败----"
        self.logger.info(step)
        sql_cmd = f"select version();"
        sql_res = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_res)
        self.assertIn('openGauss', sql_res, "执行失败:" + step)

        step = "--step3:重启数据库 expect:失败--"
        self.logger.info(step)
        stop_res = self.primary_sh.exec_cm_ctl('stop')
        self.logger.info(stop_res)
        self.assertIn(self.constant.cm_stop_success_msg, stop_res,
                      "执行失败:" + step)
        start_res = self.primary_sh.exec_cm_ctl('start', '-t 120')
        self.logger.info(start_res)
        self.assertIn(self.constant.cm_start_failed_msg, stop_res,
                      "执行失败:" + step)

        step = "--step4:恢复文件 expect:成功--"
        self.logger.info(step)
        self.logger.info("--删除损坏文件--")
        rm_cmd = f'dsscmd rm -p +{data_vgname}/pg_control'
        self.logger.info(rm_cmd)
        rm_res = self.primary_node.sh(rm_cmd).result().strip()
        self.logger.info(rm_res)
        self.assertEqual("Succeed to remove device", rm_res, "执行失败:" + step)
        self.logger.info("--使用备份恢复文件--")
        restore_cmd = f"dsscmd cp -s +{data_vgname}/pg_control.backup -d " \
                      f"+{data_vgname}/pg_control"
        self.logger.info(restore_cmd)
        restore_res = self.primary_node.sh(restore_cmd).result().strip()
        self.logger.info(restore_res)
        self.assertEqual("Succeed to copy file", restore_res, "执行失败:" + step)

        step = "--step5:启动数据库 expect:成功--"
        self.logger.info(step)
        start_res = self.primary_sh.exec_cm_ctl('start', '-t 120')
        self.logger.info(start_res)
        self.assertIn(self.constant.cm_start_success_msg, start_res,
                      "执行失败:" + step)

        step = "----step6:连接数据库，查询集群状态 expect:成功----"
        self.logger.info(step)
        sql_cmd = f"select version();"
        sql_res = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_res)
        self.assertIn('openGauss', sql_res, "执行失败:" + step)
        cluster_res = self.primary_sh.exec_cm_ctl('query', '-Cvidpw')
        self.logger.info(cluster_res)
        self.assertIn('cluster_state   : Normal', cluster_res,
                      "执行失败:" + step)

    def tearDown(self):
        self.logger.info(f"----{os.path.basename(__file__)} end----")
